package _go

/*148. 排序链表
难度
中等

1145

收藏

分享
切换为英文
接收动态
反馈
给你链表的头结点 head ，请将其按 升序 排列并返回 排序后的链表 。

进阶：

你可以在 O(n log n) 时间复杂度和常数级空间复杂度下，对链表进行排序吗？


示例 1：


输入：head = [4,2,1,3]
输出：[1,2,3,4]
示例 2：


输入：head = [-1,5,3,4,0]
输出：[-1,0,3,4,5]
示例 3：

输入：head = []
输出：[]


提示：

链表中节点的数目在范围 [0, 5 * 104] 内
-105 <= Node.val <= 105
*/
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func sortList(head *ListNode) *ListNode {
	return sort(head, nil)
}

func sort(head, tail *ListNode) *ListNode {
	if head == nil {
		return nil
	}
	//传入的链表只有一个的时候
	if head.Next == tail {
		//分割列表
		head.Next = nil
		return head
	}
	//算出中间值
	f, s := head, head
	for f != tail {
		f = f.Next
		if f != tail {
			f = f.Next
		}
		s = s.Next
	}
	min := s
	//合并两个 子有序链表
	return merge(sort(head, min), sort(s, tail))
}

//合并两个有序链表
func merge(head1, head2 *ListNode) *ListNode {
	if head1 == nil {
		return head2
	}
	if head2 == nil {
		return head1
	}

	tmp := &ListNode{}
	tmp1 := head1
	tmp2 := head2
	res := tmp

	for tmp1 != nil && tmp2 != nil {
		if tmp1.Val >= tmp2.Val {
			tmp.Next = tmp2
			tmp2 = tmp2.Next
		} else {
			tmp.Next = tmp1
			tmp1 = tmp1.Next
		}
		tmp = tmp.Next
	}
	if tmp1 != nil {
		tmp.Next = tmp1
	}
	if tmp2 != nil {
		tmp.Next = tmp2
	}
	return res.Next
}
